package client;

//test
import java.net.*;
import java.util.StringTokenizer;
import java.io.*;

import server.ChatServer;
import start.MainFrame;

public class ChatClient implements Runnable

{
	private Socket socket = null;
	private Thread thread = null;
	private DataInputStream console = null;
	private DataOutputStream streamOut = null;
	private ChatClientThread client = null;

	private String[] nickListe = new String[50];
	private int nickNumber = 0;
	//
	private String clientname = "";
	//
	private MainFrame mainFrame;
	private ChatFenster chatFenster;

	//
	//

	public ChatClient(MainFrame mainFrame, ChatFenster chatFenster) {

		this.mainFrame = mainFrame;
		this.chatFenster = chatFenster;

		chatFenster.appendToChat("Verbinde, bitte warten. ...");

		try {
			// TODO Sollten vorher ueberprueft werden(Port sollte ne Zahl sein
			// etc., vllt. Utilities einbauen nen check, wird ja mehrmals
			// verwendet)

			if (mainFrame.getPort().length() <= 1) {
				chatFenster
						.appendToChat("Fehlerhafter Port, bitte korrigieren");
				return;
			}

			if (mainFrame.getPort().contains("[a-zA-Z]")) {
				chatFenster
						.appendToChat("Es sind keine Buchstaben im Port erlaubt");
				return;
			}

			socket = new Socket(mainFrame.getIP(), Integer.parseInt(mainFrame
					.getPort()));
			chatFenster.appendToChat("Verbunden: " + socket);
			chatFenster
					.appendToChat("\n\nF\u00FCr das Verlassen bitte \".bye\" eingeben");
			start();
		} catch (UnknownHostException uhe) {
			chatFenster.appendToChat("Unbekannter Server: " + uhe.getMessage());
		} catch (IOException ioe) {
			chatFenster
					.appendToChat("Unerwarteter Fehler: " + ioe.getMessage());
		}

	}

	public void run() {

		try {
			streamOut.writeUTF(".nickstart" + ChatServer.LIMITER
					+ mainFrame.getNickname());
		} catch (IOException e) {
			e.printStackTrace();
		}

		while (thread != null) {
			try {
				if (chatFenster.sendMsg()) {
					// TODO Der Nick sollte keine sonderzeichen enthalten ( kann
					// passieren, dass dann alle nicht mehr angezeigt werden

					if (chatFenster.getEnterText().startsWith(
							".nick" + ChatServer.LIMITER)) {
						streamOut.writeUTF(chatFenster.getEnterText()
								+ ChatServer.LIMITER + mainFrame.getNickname());
						java.util.StringTokenizer st = new java.util.StringTokenizer(
								chatFenster.getEnterText(), ChatServer.LIMITER);
						clientname = st.nextToken();
						clientname = st.nextToken(); // TODO umstaendlich
						streamOut.flush();
						chatFenster.setSendMsg(false);
					} else {

						// TODO oder im Chat ausgeben lassen ?!?!? hmmhmhmhm (
						// der
						// fehler wird das aufjedenfall!)

						// TODO Text zu lang oder zu kurz sollte nicht gesendet
						// werden - entweder filtern oder messagesbox und dann
						// reseten

						chatFenster.setSendMsg(false);

						if (chatFenster.getEnterText().length() >= 50) {
							chatFenster.setEnterText("Text zu lang");
						} else if (chatFenster.getEnterText().length() < 1) {
							chatFenster.setEnterText("Text zu kurz");
						} else {
							streamOut.writeUTF(chatFenster.getEnterText());
							streamOut.flush();
							chatFenster.setEnterText("");
						}
					}
				}
			} catch (IOException ioe) {
				chatFenster.appendToChat("!! Fehler: " + ioe.getMessage());
				stop();
			}
		}
	}

	public void handle(String msg) {
		int pos = 0;
		pos = msg.indexOf(".bye");
		if (pos > 1) {
			// TODO mal schauen, ob es immer der richtige clientname ist
			chatFenster.appendToChat("\nTsch\u00FC\u00DF ..." + clientname);
			chatFenster.scrollChat();
			stop();
		} else if (msg.startsWith(ChatServer.LIMITER)) { // Das ist die
															// Nickliste
			chatFenster.appendToChat("");
			StringTokenizer st = new StringTokenizer(msg, ChatServer.LIMITER);
			while (st.hasMoreTokens()) {
				nickListe[nickNumber] = st.nextToken();
				nickNumber++;
			}
			for (int ind = 0; ind < nickNumber; ind++) {
				chatFenster.appendToChat(nickListe[ind] + "\n");
				chatFenster.appendToContacts(nickListe[ind] + "\n");
			}
			nickNumber = 0;

		} else {
			chatFenster.appendToChat("\n" + msg);
		}
		chatFenster.scrollChat();
	}

	public void start() throws IOException {
		console = new DataInputStream(System.in);
		streamOut = new DataOutputStream(socket.getOutputStream());
		if (thread == null) {
			client = new ChatClientThread(this, socket, chatFenster);
			thread = new Thread(this);
			thread.start();
		}
	}

	@SuppressWarnings("deprecation")
	public void stop() {
		if (thread != null) {
			thread.stop();
			thread = null;
		}
		try {
			if (console != null)
				console.close();
			if (streamOut != null)
				streamOut.close();
			if (socket != null)
				socket.close();
		} catch (IOException ioe) {
			chatFenster.appendToChat("Fehler ..." + ioe);
		}
		client.close();
		client.stop();
	}

	// ******************************************************
	// ******************************************************
	// ******************************************************
	// Access
	// ******************************************************
	// ******************************************************
	// ******************************************************

	public DataInputStream getDIS() {
		return console;
	}

	public DataOutputStream getDOS() {
		return streamOut;
	}

	public ChatClientThread getclient() {
		return client;
	}

	public Socket getsocket() {
		return socket;
	}

}
